# backend/schemas/user_subscription.py
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, Field, model_validator
from typing import Optional, List


class UserSubscriptionBase(BaseModel):
    user_id: UUID
    subscription_id: UUID
    node_id: UUID
    expires_at: datetime
    is_active: bool = True
    used_traffic_mb: int = 0
    status_notes: Optional[str] = None


class UserSubscriptionCreate(UserSubscriptionBase):
    pass


class UserSubscriptionUpdate(BaseModel):
    is_active: Optional[bool] = None
    used_traffic_mb: Optional[int] = None
    status_notes: Optional[str] = None


class UserSubscriptionOut(UserSubscriptionBase):
    id: UUID
    started_at: datetime

    class Config:
        from_attributes = True


# 节点切换相关的模型
class UserSubscriptionSwitchNode(BaseModel):
    new_node_id: Optional[str] = Field(
        None,
        description="新节点ID",
        example="a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        min_length=36,
        max_length=36
    )
    node_id: Optional[str] = Field(
        None,
        description="新节点ID（兼容字段）",
        example="a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        min_length=36,
        max_length=36
    )

    @model_validator(mode='after')
    def validate_node_id(self):
        """验证节点ID，兼容 new_node_id 和 node_id 两种参数"""
        # 记录调试信息
        print(f"🔍 Schema验证 - new_node_id: {self.new_node_id}, node_id: {self.node_id}")

        # 如果两个字段都提供了，优先使用 new_node_id
        if self.new_node_id and self.node_id:
            print("⚠️  同时提供了 new_node_id 和 node_id，优先使用 new_node_id")
            return self
        elif self.new_node_id:
            print("✅ 使用 new_node_id 参数")
            return self
        elif self.node_id:
            print("🔄 使用 node_id 参数（兼容模式）")
            self.new_node_id = self.node_id
            return self
        else:
            raise ValueError('必须提供 new_node_id 或 node_id 参数')

    def get_final_node_id(self) -> str:
        """获取最终使用的节点ID"""
        return self.new_node_id


class UserSubscriptionSwitchResponse(BaseModel):
    success: bool
    message: str
    new_node_id: str
    client_ip: Optional[str] = None
    config_updated: bool


# 用户订阅详情模型
class UserSubscriptionDetail(UserSubscriptionOut):
    subscription_name: Optional[str] = None
    node_name: Optional[str] = None
    node_location: Optional[str] = None
    remaining_days: Optional[int] = None
    data_usage_percent: Optional[float] = None


# 用户订阅列表响应模型
class UserSubscriptionListResponse(BaseModel):
    subscriptions: List[UserSubscriptionDetail]
    total_count: int
    active_count: int


# 流量统计模型
class TrafficUsage(BaseModel):
    used_traffic_mb: int
    total_traffic_mb: Optional[int] = None
    usage_percent: Optional[float] = None
    remaining_traffic_mb: Optional[int] = None


# 订阅状态模型
class SubscriptionStatus(BaseModel):
    is_active: bool
    is_expired: bool
    remaining_days: int
    can_switch_node: bool
    reason: Optional[str] = None


# 续订订阅模型
class UserSubscriptionRenew(BaseModel):
    extend_days: int = Field(..., ge=1, le=365, description="续订天数")
    auto_renew: bool = False


class UserSubscriptionRenewResponse(BaseModel):
    success: bool
    message: str
    new_expires_at: datetime
    extended_days: int
    total_paid: Optional[float] = None


# 取消订阅模型
class UserSubscriptionCancel(BaseModel):
    reason: Optional[str] = None
    feedback: Optional[str] = None


class UserSubscriptionCancelResponse(BaseModel):
    success: bool
    message: str
    cancelled_at: datetime
    refund_amount: Optional[float] = None


# 订阅统计模型
class SubscriptionStats(BaseModel):
    total_subscriptions: int
    active_subscriptions: int
    expired_subscriptions: int
    total_revenue: float
    average_usage_mb: float


# 节点使用情况模型
class NodeUsageStats(BaseModel):
    node_id: UUID
    node_name: str
    active_subscriptions: int
    total_usage_mb: int
    usage_percent: float


# WireGuard配置更新模型
class WireGuardConfigUpdate(BaseModel):
    client_ip: Optional[str] = Field(None, description="客户端IP地址")
    regenerate_keys: bool = Field(False, description="是否重新生成密钥对")


class WireGuardConfigUpdateResponse(BaseModel):
    success: bool
    message: str
    client_ip: Optional[str] = None
    public_key: Optional[str] = None
    config_updated: bool


# 批量操作模型
class BatchSubscriptionUpdate(BaseModel):
    subscription_ids: List[UUID] = Field(..., min_items=1, max_items=100)
    is_active: Optional[bool] = None
    node_id: Optional[UUID] = None


class BatchOperationResponse(BaseModel):
    success: bool
    processed_count: int
    success_count: int
    failed_count: int
    errors: List[str] = []


# 订阅搜索和过滤模型
class SubscriptionFilter(BaseModel):
    user_id: Optional[UUID] = None
    node_id: Optional[UUID] = None
    subscription_id: Optional[UUID] = None
    is_active: Optional[bool] = None
    is_expired: Optional[bool] = None
    min_created_at: Optional[datetime] = None
    max_created_at: Optional[datetime] = None


class SubscriptionSearchResponse(BaseModel):
    results: List[UserSubscriptionDetail]
    total: int
    page: int
    page_size: int
    total_pages: int


# 导出和导入模型
class UserSubscriptionExport(BaseModel):
    format: str = Field("json", pattern="^(json|csv)$")


class UserSubscriptionImport(BaseModel):
    data: List[UserSubscriptionCreate]
    overwrite_existing: bool = False


class ImportExportResponse(BaseModel):
    success: bool
    message: str
    processed_count: int
    file_url: Optional[str] = None
    file_size: Optional[int] = None


# Webhook和通知模型
class SubscriptionWebhook(BaseModel):
    event_type: str = Field(..., description="事件类型")
    subscription_id: UUID
    user_id: UUID
    data: dict
    timestamp: datetime


class WebhookResponse(BaseModel):
    success: bool
    message: str
    event_id: str


# 订阅计划升级模型
class SubscriptionUpgrade(BaseModel):
    new_subscription_id: UUID
    prorated: bool = True
    immediate: bool = False


class SubscriptionUpgradeResponse(BaseModel):
    success: bool
    message: str
    old_subscription_id: UUID
    new_subscription_id: UUID
    price_difference: Optional[float] = None
    effective_date: datetime


# 订阅暂停模型
class SubscriptionPause(BaseModel):
    pause_days: int = Field(..., ge=1, le=30, description="暂停天数")
    reason: Optional[str] = None


class SubscriptionPauseResponse(BaseModel):
    success: bool
    message: str
    paused_until: datetime
    original_expires_at: datetime
    extended_expires_at: datetime


# 订阅转移模型
class SubscriptionTransfer(BaseModel):
    new_user_id: UUID
    transfer_usage: bool = True
    notify_users: bool = True


class SubscriptionTransferResponse(BaseModel):
    success: bool
    message: str
    from_user_id: UUID
    to_user_id: UUID
    transferred_at: datetime


# API响应包装模型
class APIResponse(BaseModel):
    success: bool
    message: str
    data: Optional[dict] = None
    errors: Optional[List[str]] = None


class PaginationParams(BaseModel):
    page: int = Field(1, ge=1)
    page_size: int = Field(10, ge=1, le=100)
    sort_by: str = "created_at"
    sort_order: str = Field("desc", pattern="^(asc|desc)$")


# 验证器函数（可选）
def validate_subscription_dates(cls, values):
    """验证订阅日期逻辑"""
    started_at = values.get('started_at')
    expires_at = values.get('expires_at')

    if started_at and expires_at and expires_at <= started_at:
        raise ValueError('过期时间必须大于开始时间')

    return values


# 如果需要，可以为特定模型添加验证
UserSubscriptionCreate.model_rebuild()
UserSubscriptionOut.model_rebuild()